﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SLBehaviourSystem
{
    public abstract class BehaviourNodeBase
    {
        public int Id;

        public BehaviourAgent Agent;
        protected BehaviourNodeBase root;
        protected List<BehaviourNodeBase> childNodes = new List<BehaviourNodeBase>();
        protected BehaviourNodeBase parent;
        public BehaviourComponent Component;
        public BehaviourInterruptType InteruptType;
        public BehaviourExcuteType ExcuteType;


        public BehaviourNodeState CurNodeState {
            get
            {
                return curNodeState;
            }
        }
        protected BehaviourNodeState curNodeState = BehaviourNodeState.Idle;

        public void SetCurNodeState(BehaviourNodeState curNodeState)
        {
            this.curNodeState = curNodeState;
        }

        public IDataContainer BehaviourData {
            get { return behaviourData; }
            set {
                behaviourData = value;
                OnInitData();
            }
        }
        protected IDataContainer behaviourData;

        public void SetRoot(BehaviourNodeBase root)
        {
            this.root = root;
            Agent = this.root.Agent;
        }

        public virtual void AddChild(BehaviourNodeBase node)
        {
            if (root == null)
            {
                node.SetRoot(this);
            }
            else
            {
                node.SetRoot(root);
            }
            childNodes.Add(node);
            node.parent = this;
            if (node.behaviourData == null)
            {
                node.BehaviourData = new DataContainer();
            }
            else
            {
                node.OnInitData();
            }
        }

        protected virtual void OnInitData()
        {

        }

        public virtual BehaviourNodeState Excute()
        {
            OnExcute();
            
            return curNodeState;
        }

        protected virtual void OnExcute()
        {

        }

        public void Interupt()
        {
            curNodeState = BehaviourNodeState.Idle;
            OnInterupt();
            Reset();
        }

        protected virtual void OnInterupt()
        {

        }

        public void ChildNodeComplete()
        {
            OnChildNodeComplete();
        }

        protected virtual void OnChildNodeComplete()
        {
            
        }

        public void Reset()
        {
            curNodeState = BehaviourNodeState.Idle;
            
            for (int i = 0; i < childNodes.Count; i++)
            {
                childNodes[i].Reset();
            }
            OnReset();
        }

        protected virtual void OnReset()
        {

        }


        public void LogStates()
        {
            for (int i = 0; i < childNodes.Count; i++)
            {
                DebugUtils.Log("Id" + childNodes[i].Id + "  " + childNodes[i].CurNodeState);
                childNodes[i].LogStates();
            }
        }
    }
}
